<script setup>
import CmpEdit from '@/views/liteflow/cmp/CmpEditTabs.vue'
import SettingGroup from '@/views/liteflow/logic/node-red/tools/SettingGroup.vue'
import ScrollToTop from '@core/components/ScrollToTop.vue'
import LogicFlow from '@logicflow/core'
import "@logicflow/core/dist/style/index.css"
import { Control, Group, InsertNodeInPolyline, Menu, MiniMap, SelectionSelect, Snapshot } from "@logicflow/extension"
import "@logicflow/extension/lib/style/index.css"
import { onMounted, ref, watch } from 'vue'
import AppCardCode from './AppCardCode.vue'
import NodeRedExtension from './node-red/index'
import './node-red/style.css'
import SettingEdge from './node-red/tools/SettingEdge2.vue'


const props = defineProps({		
  currRow: Object,
  operType: Number,
})

const emits = defineEmits(['closeFlowChart'])

const currRow = ref(props.currRow || {})

const closeFlowChartShow = ref(props.currRow || false)
const operType = ref(props.operType || -1)
const count = ref(0)
const currentNode = ref(null)
const currentEdge = ref(null)
const currentEdgeSource = ref(null)
const currentEdgeTarget = ref(null)
const currentNodeVisible = ref(false)
const currentEdgeVisible = ref(false)


const settingEdgeKey = ref(1)
const container = ref()
const lf = ref()
const toggleExclusive = ref(1)
const settingKey = ref(1)

const jsonCurrentTab = ref(0)
const isDialogJSONVisible = ref(false)
const jsonDialogContent = ref('')
const jsonDialogAllContent = ref('')

const isDialogELVisible = ref(false)
const elDialogContent = ref('')

const isDialogELExecVisible = ref(false)
const elExecDialogContent = ref('')

const isDialogImportVisible = ref(false)
const importDialogContent = ref('')

const formatEL = ref(true)
const realTimeEL = ref(currRow.value.el || '')
const realTimeColor = ref(currRow.value.el ? 'success' : 'primary')

const file = ref()
const file_loading = ref(true)

watch(formatEL, () =>{
  elDialogClick()
})

watch(file, () => {
  const f = file.value[0]

  file_loading.value = !f
  if(f){
    const reader = new FileReader()

    reader.onload = () => {
      const fileData = reader.result

      importDialogContent.value = fileData
    }
    reader.readAsText(f)
  }
})

onMounted(() => {
  initializeResizableDiv()

  lf.value = new LogicFlow({
    // 容器配置
    container: container.value,

    // 画布配置
    // width: 700,
    // height: 500,
    // background: {
    //   color: '#F0F0F0'
    // },
    grid: {
      visible: true,
      type: 'mesh', //dot,mesh
      size: 10,
      config: {
        color: '#eeeeee',
      },
    },

    // 样式配置
    // style: {
    //   rect: {
    //     radius: 6,
    //   },
    // },
    
    // 工具配置
    // textEdit: true,
    // isSilentMode: false,
    // edgeType: 'line',
    // snapline: true,

    // stopMoveGraph: true,
    // adjustEdge: false,
    hideAnchors: false, //是否隐藏节点的锚点，静默模式下默认隐藏
    hoverOutline: true,
    edgeSelectedOutline: true,
    nodeTextDraggable: false, //允许节点文本可以拖拽
    edgeTextDraggable: false, //允许连线文本可以拖拽
    keyboard: {
      enabled: true,
    },

    // keyboard: true,
    plugins: [
      NodeRedExtension,
      Menu,
      Control,
      SelectionSelect, 
      MiniMap, 
      Group, 
      InsertNodeInPolyline, 
      Snapshot, 
    ],
  })

  // 导航菜单
  lf.value.extension.control.addItem({
    key: 'mini-map',
    iconClass: 'lf-local-mini-map',
    title: "",
    text: "导航",
    onClick: (lf, ev) => {
      const position = lf.getPointByClient(ev.x, ev.y)

      lf.extension.miniMap.show(
        position.domOverlayPosition.x - 120,
        position.domOverlayPosition.y + 35,
      )
    },
  })

  lf.value.extension.menu.addMenuConfig({
    nodeMenu: [
      // {
      //   text: "分享",
      //   callback() {
      //     alert("分享成功！");
      //   },
      // },
      // {
      //   text: "设置属性",
      //   callback(node) {
      //     addVisible.value = true
      //     currentNode.value = node
      //   },
      // },
    ],
    edgeMenu: [
      // {
      //   text: "属性",
      //   callback(edge) {
      //     alert(`
      //       边id：${edge.id}
      //       边类型：${edge.type}
      //       边坐标：(x: ${edge.x}, y: ${edge.y})
      //       源节点id：${edge.sourceNodeId}
      //       目标节点id：${edge.targetNodeId}`);
      //   },
      // },
    ],
    graphMenu: [
      // {
      //   text: "分享",
      //   callback() {
      //     alert("分享成功！");
      //   },
      // },
    ],
  });

  //渲染画布
  lf.value.render(currRow.value.sourceJson ? JSON.parse(currRow.value.sourceJson) : {})

  lf.value.on('node-red:start', () => {
    console.log('执行流程')
  })

  //节点点击事件
  lf.value.on('node:click', ({ data }) => {
    currentNode.value = null
    settingKey.value = settingKey.value + 1
    currentNode.value = data
    currentNodeVisible.value = true
    currentEdgeVisible.value = false
    
    if(data.type == 'GroupParallel'){
      resizableDiv.value.style.zIndex = 1005
      showSettingGroupDialog(data)
    }else{
      resizableDiv.value.style.zIndex = 1005
      showSettingDialog()
    }
  })

  //线点击事件
  lf.value.on('edge:click', ({ data }) => {
    settingEdgeKey.value = settingEdgeKey.value + 1
    currentEdge.value = data
    currentEdgeSource.value = lf.value.getNodeModelById(data.sourceNodeId)
    currentEdgeTarget.value = lf.value.getNodeModelById(data.targetNodeId)
    currentEdgeVisible.value = true
    currentNodeVisible.value = false
  })

  // 点击空白画布
  lf.value.on('blank:click', ({ data }) => {
    currentNodeVisible.value = false
    currentEdgeVisible.value = false
    currentNode.value = null
    currentEdge.value = null
    currentEdgeSource.value = null
    currentEdgeTarget.value = null
    lf.value.extension.miniMap.hide()

    hideSettingDialog()
    setTimeout(() => {
      resizableHandles(false)
    }, 500);
  })

  // 画布上的每一次改动，当画布上的元素发生变化时会触发
  lf.value.on('history:change', ({ data }) => {
    lfElValidate()
  })

  // 外部拖入节点添加时触发
  // lf.value.on('node:dnd-add', ({ data, e }) => {
  //   console.log('node:dnd-add data', data)
  //   console.log('node:dnd-add e', e)
  // })

  // 外部拖入节点拖拽中触发
  // lf.value.on('node:dnd-drag', ({ data,e,position }) => {
  //   console.log('node:dnd-drag', data)
  // })

  // 默认框选
  openSelectionSelect()
})

const lfElValidate = async () => {
  const res = await $ivyApi.post(API_URLS.lfElValidate, {
    json: JSON.stringify(getSimpleGraphData(), null, 2),
    formatEL: false,
  })

  if(res.code == -1){
    realTimeColor.value = 'primary'
    realTimeEL.value = res.data
  }else if(res.code == 200){
    realTimeColor.value = 'success'
    realTimeEL.value = res.data
  }else{
    realTimeColor.value = 'error'
    realTimeEL.value = res.message
  }
}

const changeStyle = style => {
  lf.value.setProperties(currentNode.value.id, { style })
}

const setNodeProp = obj => {
  if(currentNode.value){
    lf.value.getNodeModelById(currentNode.value.id).setProperties(obj)
    if(obj.componentName){
      lf.value.updateText(currentNode.value.id, obj.componentName)
    }
  }
}

const setEdgeProp = obj => {
  lf.value.getEdgeModelById(currentEdge.value.id).setProperties(obj)
  if(obj.linkType == 1){
    lf.value.updateText(currentEdge.value.id, 'switch')
  }else if(obj.linkType == 2){
    lf.value.updateText(currentEdge.value.id, 'default')
  }else if(obj.linkType == 3){
    lf.value.updateText(currentEdge.value.id, 'true')
  }else if(obj.linkType == 4){
    lf.value.updateText(currentEdge.value.id, 'false')
  }else if(obj.linkType == 5){
    lf.value.updateText(currentEdge.value.id, 'do')
  }else if(obj.linkType == 6){
    lf.value.updateText(currentEdge.value.id, 'do')
  }else if(obj.linkType == 7){
    lf.value.updateText(currentEdge.value.id, 'do')
  }else if(obj.linkType == 8){
    lf.value.updateText(currentEdge.value.id, 'break')
  }
  
}

// const setEdgeSwitchProp = obj => {
//   lf.value.getEdgeModelById(currentEdge.value.id).setProperties(obj)
//   lf.value.updateText(currentEdge.value.id, obj.switchType)
// }

// const setEdgeIfProp = obj => {
//   lf.value.getEdgeModelById(currentEdge.value.id).setProperties(obj)
//   lf.value.updateText(currentEdge.value.id, obj.ifType)
// }

const openSelectionSelect = () => {
  lf.value.extension.selectionSelect.openSelectionSelect()
}

const closeSelectionSelect = () => {
  lf.value.extension.selectionSelect.closeSelectionSelect()
}

const jsonDialogClick = () => {
  isDialogJSONVisible.value = !isDialogJSONVisible.value
  jsonDialogContent.value = { "js": JSON.stringify(getSimpleGraphData(), null, 2) }
  jsonDialogAllContent.value = { "js": JSON.stringify(lf.value.getGraphData(), null, 2) }
}

const elDialogClick = async () => {
  isDialogELVisible.value = true
  elDialogContent.value = ''
  elExecDialogContent.value = ''

  const res = await $ivyApi.post(API_URLS.lfElBuild, {
    json: JSON.stringify(getSimpleGraphData(), null, 2),
    formatEL: formatEL.value,
  })

  elDialogContent.value = { 'js': res.data }
}

const elExecDialogClick = async () => {
  elExecDialogContent.value = ''

  const res = await $ivyApi.post(API_URLS.lfElExec, {
    json: JSON.stringify(getSimpleGraphData(), null, 2),
  })

  elExecDialogContent.value = { 'js': res.data }
}




// 清空画布
const clearData = () => {
  lf.value.render({})
}

// 从数据库导入流程
const elOption = ref(currRow.value.id || null)
const elOptions = reactive([])
const elOptionDisabled = ref(operType.value == 3 ? true : false)
const currentEl = reactive({ elName: currRow.value.elName, elId: currRow.value.elId })

const executorOption = ref(currRow.value.executorId || null)
const executorOptions = reactive([])

const executorOptionsQuery = async () => {
  executorOptions.length = 0

  const res = await $ivyApi.post(API_URLS.lfExecutorOptions, {})

  executorOptions.push(...res.data)
}

const importDbJson = async () => {
  if(operType.value == 3){
    elOption.value = currRow.value.id
  }else{
    elOption.value = null
  }
  elOptions.length = 0

  const res = await $ivyApi.post(API_URLS.lfElOptions, {})

  elOptions.push(...res.data)
}

watch(elOption, val => {
  if(val){
    const option= elOptions.filter(item => item.id == val)[0]

    importDialogContent.value = option.sourceJson

    Object.assign(currentEl, option)
  }
})

const importDialogClick = () => {
  isDialogImportVisible.value = !isDialogImportVisible.value
  file.value = []
  importDialogContent.value = null

  importDbJson()
  executorOptionsQuery()
}

const importJsonDialogClick = () => {
  lf.value.render(JSON.parse(importDialogContent.value))
  isDialogImportVisible.value = false
}

const exportDialogClick = () => {
  const jsonData = { /* JSON数据 */ }
  const jsonStr = JSON.stringify(lf.value.getGraphData())
  const blob = new Blob([jsonStr], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')

  link.href = url
  link.download = 'data.json'
  link.click()
  URL.revokeObjectURL(url)
}

// 保存操作
const saveTab = ref(0)
const saveDialogVisible = ref(false)
const elId = ref()
const elName = ref()

const saveDialogClick = () => {
  saveDialogVisible.value = true
  elOptions.length = 0
  importDbJson()
  executorOptionsQuery()
}

const saveFlowDialogClick = async () => {
  if(saveTab.value == 0 && (currentEl && currentEl.elId)){
    if(!elOption.value){
      showMsgError("未选择表达式！")
      
      return
    }

    const res = await $ivyApi.post(API_URLS.lfElUpdate, {
      id: elOption.value,
      flowJson: JSON.stringify(getSimpleGraphData()),
      sourceJson: JSON.stringify(getFullGraphData()),
      el: realTimeEL.value,
      executorId: executorOption.value,
    })

    showMsg(res)
    if(res.code == 200){
      saveDialogVisible.value = false
    }
  }else{
    if(!elId.value){
      showMsgError("未设置表达式ID！") 
      
      return
    }
    if(!elName.value){
      showMsgError("未设置表达式名称！") 
      
      return
    }

    const res = await $ivyApi.post(API_URLS.lfElAdd, {
      elId: elId.value,
      elName: elName.value,
      flowJson: JSON.stringify(getSimpleGraphData()),
      sourceJson: JSON.stringify(getFullGraphData()),
      el: realTimeEL.value,
      executorId: executorOption.value,
    })

    showMsg(res)
    if(res.code == 200){
      saveDialogVisible.value = false
    }
  }
}

const getFullGraphData = () => {
  return lf.value.getGraphData()
}

const getSimpleGraphData = () => {
  const fullGraphData = lf.value.getGraphData()

  // 处理图数据，只保留需要的属性
  return {
    nodes: fullGraphData.nodes.map(({ id, type, properties, text, children }) => ({ id, type, properties, text: text.value, children })),
    edges: fullGraphData.edges.map(({ sourceNodeId, targetNodeId, properties, text }) => ({ sourceNodeId, targetNodeId, properties, text: text ? text.value : '' })),
  }
}

// 回调信息
const msgVisible = ref(false)
const msgContent = ref('')
const msgColor = ref('error')

const showMsg = res => {
  if(res){
    if(res.code == 200){
      msgVisible.value = true
      msgColor.value = "success"
      msgContent.value = res.message
    }else{
      msgVisible.value = true
      msgColor.value = "error"
      msgContent.value = res.message
    }
  }
}

const showMsgSuccess = msg => {
  msgVisible.value = true
  msgColor.value = "success"
  msgContent.value = msg
}

const showMsgError = msg => {
  msgVisible.value = true
  msgColor.value = "error"
  msgContent.value = msg
}


const closeFlowChart = () => {
  emits('closeFlowChart', null)
}

// 全屏显示
const fullscreenShow = ref(false)
const fullscreenIcon = ref('tabler-arrows-maximize')
const fullscreenTitle = ref('全屏显示')
const fullscreenClick = () => {
  if(fullscreenShow.value){
    fullscreenIcon.value = 'tabler-arrows-maximize'
    fullscreenTitle.value = '全屏显示'
    fullscreenShow.value = false
  }else{
    fullscreenIcon.value = 'tabler-arrows-minimize'
    fullscreenTitle.value = '退出全屏'
    fullscreenShow.value = true
  }
}

// 分组组件
const groupVisible = ref(false)
const groupKey = ref(1)
const groupRef = ref(null)
const currentGroupNode = ref()
const showSettingGroupDialog = (nodeData) => {
  addVisible.value = false
  groupVisible.value = true
  groupKey.value++
  currentGroupNode.value = nodeData
}

// 新增操作&编辑操作
const editKey = ref(1)
const addVisible = ref(false)
const operType2 = ref(2) // 操作类型：0新增，1更新,2属性设置
const currRow2 = ref({})
const showSettingDialog = () => {
  groupVisible.value = false
  addVisible.value = true
  editKey.value++
}
const hideSettingDialog = () => {
  addVisible.value = false
}

const nodeRef = ref(null)
// 当 currentNode 变化时重新渲染数据
// watch(currentNode, (newValue, oldValue) => {
//   // 在这里可以执行任何你想要的操作，比如重新渲染组件数据
//   // console.log('currentNode changed:', newValue);
//   nodeRef.value.updateNodeData(newValue);
// }, { deep: true });

const resizableDiv = ref(null)

const initializeResizableDiv = () => {
  const resizableHandle = document.createElement('div')

  resizableHandle.className = 'resizable-handle'
  resizableDiv.value.appendChild(resizableHandle)

  let initialX = 0
  let initialWidth = 0

  const startDrag = e => {
    e.preventDefault()
    initialX = e.clientX
    initialWidth = resizableDiv.value.offsetWidth
    document.addEventListener('mousemove', doDrag)
    document.addEventListener('mouseup', stopDrag)
  }

  const doDrag = e => {
    const newWidth = initialWidth - (e.clientX - initialX)
    if(newWidth < 800){
      resizableDiv.value.style.width = newWidth + 'px'
    }
  }

  const stopDrag = () => {
    document.removeEventListener('mousemove', doDrag)
    document.removeEventListener('mouseup', stopDrag)
  }

  resizableHandle.addEventListener('mousedown', startDrag)
}

const resizableHandles = (flag) => {
  if(!flag){
    resizableDiv.value.style.zIndex = -1
  }else{
    resizableDiv.value.style.zIndex = 1005
  }
}
</script>

<template>
  <div :class="{'flow-chart-root': (!closeFlowChartShow && !fullscreenShow),'flow-chart-root2': closeFlowChartShow,'fullscreen-div': fullscreenShow}">
    <VSnackbar
      v-model="msgVisible"
      location="top"
      :color="msgColor"
    >
      {{ msgContent }}
    </VSnackbar>

    <div class="button-group">
      <VBtn
        size="small"
        @click="clearData"
      >
        清空画布
      </VBtn>
      <VBtn
        size="small"
        @click="closeSelectionSelect"
      >
        拖动画布
      </VBtn>
      <VBtn
        size="small"
        @click="openSelectionSelect"
      >
        框选节点
      </VBtn>
      <VBtn
        size="small"
        @click="importDialogClick"
      >
        导入数据
      </VBtn>
      <VBtn
        size="small"
        @click="exportDialogClick"
      >
        导出数据
      </VBtn>

      <VBtn
        size="small"
        @click="jsonDialogClick"
      >
        预览数据
      </VBtn>
      <VBtn
        size="small"
        @click="elDialogClick"
      >
        生成EL表达式
      </VBtn>
      
      <VBtn
        size="small"
        @click="saveDialogClick"
      >
        <VIcon
          start
          icon="tabler-file"
        />
        保存
      </VBtn>

      <!--
        <VBtn
        size="small"
        style="float: inline-end;"
        >
        <VIcon
        start
        icon="tabler-settings"
        />
        设置
        </VBtn> 
      -->
      <VBtn
        v-if="closeFlowChartShow"
        size="small"
        color="error"
        style="float: inline-end;"
        @click="closeFlowChart"
      >
        <VIcon
          start
          icon="tabler-x"
        />
        关闭
      </VBtn>
      <VBtn
        v-if="!closeFlowChartShow"
        size="small"
        color="primary"
        style="float: inline-end;"
        @click="fullscreenClick"
      >
        <VIcon
          start
          :icon="fullscreenIcon"
        />
        {{fullscreenTitle}}
      </VBtn>
    </div>
  
    <div class="flow-chart">
      <div
        ref="container"
        class="container"
      />
      <VAlert
        :color="realTimeColor"
        class="flow-alert"
      >
        EL表达式：{{ realTimeEL }}
      </VAlert>

      <VAlert
        :color="realTimeColor"
        class="flow-alert-top"
      >
        当前流程：{{ currentEl.elName || '' }} {{ '【'+(currentEl.elId || '')+'】' }}
      </VAlert>

      <!-- <Setting
        v-if="currentNodeVisible"
        :key="'settingKey-'+settingKey"
        :node-data="currentNode"
        class="setting-panel"
        @change-style="changeStyle"
        @set-node-prop="setNodeProp"
        @showSettingDialog="showSettingDialog"
      /> -->

      <SettingEdge
        v-if="currentEdgeVisible"
        :key="'settingEdgeKey-'+settingEdgeKey"
        :edge-data="currentEdge"
        :edge-source-data="currentEdgeSource"
        :edge-target-data="currentEdgeTarget"
        class="setting-panel"
        @set-edge-prop="setEdgeProp"
      />

      <div
        ref="resizableDiv"
        class="setting-panel resizable-div"
      >
        <CmpEdit
          v-show="addVisible"
          ref="nodeRef"
          :key="'cmp-edit-'+editKey"
          v-model:isDrawerOpen="addVisible"
          :oper-type="operType2"
          :curr-row="currRow2"
          @set-node-prop="setNodeProp"
          @resizableHandle="resizableHandles"
          :node-data="currentNode"
          @showSettingDialog="showSettingDialog"
        /> 

        <SettingGroup
          v-if="groupVisible"
          ref="groupRef"
          :key="'cmp-group-'+groupKey"
          v-model:isDrawerOpen="groupVisible"
          :oper-type="operType2"
          :node-data="currentGroupNode"
          @set-node-prop="setNodeProp"
          @resizableHandle="resizableHandles"
        /> 
      </div>

      <VDialog
        v-model="isDialogJSONVisible"
        scrollable
        width="800"
        class="ivy-dialog"
      >
        <DialogCloseBtn @click="isDialogJSONVisible = !isDialogJSONVisible" />
      
        <VCard>
          <VCardItem class="pb-5">
            <VCardTitle>预览JSON</VCardTitle>
          </VCardItem>
          <VDivider />
          <VCardText>
            <VTabs
              v-model="jsonCurrentTab"
              class="v-tabs-pill"
            >
              <VTab>流程数据</VTab>
              <VTab>原始数据</VTab>
            </VTabs>

            <VCard class="mt-5 view-json">
              <VCardText class="view-json-text">
                <VWindow v-model="jsonCurrentTab">
                  <VWindowItem>
                    <AppCardCode
                      title="标题"
                      code-language="js"
                      :code="jsonDialogContent"
                      no-padding
                      show-code
                      :show-title="false"
                    />
                  </VWindowItem>
                  <VWindowItem>
                    <AppCardCode
                      title="标题"
                      code-language="js"
                      :code="jsonDialogAllContent"
                      no-padding
                      show-code
                      :show-title="false"
                    />
                  </VWindowItem>
                </VWindow>
                <ScrollToTop />
              </VCardText>
            </VCard>
          </VCardText>
        </VCard>
      </VDialog>

      <VDialog
        v-model="isDialogELVisible"
        scrollable
        width="800"
        class="ivy-dialog"
      >
        <DialogCloseBtn @click="isDialogELVisible = !isDialogELVisible" />
      
        <VCard>
          <VCardItem class="pb-5">
            <VCardTitle>EL表达式</VCardTitle>
          </VCardItem>
          <VDivider />
          <VCardText>
            <div class="button-group">
              <VBtn
                size="small"
                @click="formatEL = true"
              >
                格式化数据
              </VBtn>
              <VBtn
                size="small"
                @click="formatEL = false"
              >
                非格式化数据
              </VBtn>
            </div>
            <AppCardCode
              title=""
              code-language="js"
              :code="elDialogContent"
              no-padding
              show-code
              :show-title="false"
            />
            <VBtn
              size="small"
              @click="elExecDialogClick"
            >
              执行EL表达式
            </VBtn>
          
            <AppCardCode
              title=""
              code-language="js"
              :code="elExecDialogContent"
              no-padding
              show-code
              :show-title="false"
              class="el-code"
            />
          </VCardText>
        </VCard>
      </VDialog>

      <VDialog
        v-model="isDialogImportVisible"
        scrollable
        width="800"
        class="ivy-dialog"
      >
        <DialogCloseBtn @click="isDialogImportVisible = !isDialogImportVisible" />
      
        <VCard>
          <VCardItem class="pb-5">
            <VCardTitle>导入JSON数据</VCardTitle>
          </VCardItem>
          <VDivider />
          <VCardText>
            <VRow>
              <VCol cols="9">
                <VAutocomplete
                  v-model="elOption"
                  class="flow-mb-12"
                  variant="outlined"
                  label="选择EL配置"
                  :items="elOptions"
                  item-title="elName"
                  item-value="id"
                  clearable
                />
              </VCol>
              <VCol cols="3">
                <VBtn
                  style="inline-size: 100%;"
                  @click="importJsonDialogClick"
                >
                  导入数据
                </VBtn>
              </VCol>
            </VRow>
            
            <VFileInput
              v-model="file"
              :loading="file_loading"
              accept=".txt, .json"
              label="选择logic flow json数据文件"
              style="margin-block-end: 16px;"
            />
            <AppTextarea
              v-model="importDialogContent"
              label=""
              auto-grow
              variant="outlined"
              clearable
              clear-icon="tabler-circle-x"
              counter
            />
            <VBtn
              size="small"
              style="inline-size: 100%;"
              @click="importJsonDialogClick"
            >
              导入数据
            </VBtn>
          </VCardText>
        </VCard>
      </VDialog>


      <VDialog
        v-model="saveDialogVisible"
        scrollable
        width="800"
        class="ivy-dialog"
      >
        <DialogCloseBtn @click="saveDialogVisible = !saveDialogVisible" />
      
        <VCard>
          <VCardItem class="pb-5">
            <VCardTitle>保存流程</VCardTitle>
          </VCardItem>
          <VDivider />
          <VCardText>
            <VTabs
              v-model="saveTab"
              class="v-tabs-pill"
            >
              <VTab v-if="operType == -1 || operType == 3">
                <VIcon
                  start
                  icon="tabler-user"
                />覆盖已有流程
              </VTab>
              <VTab v-if="operType == -1 || operType == 2">
                <VIcon
                  start
                  icon="tabler-lock"
                />保存为新流程
              </VTab>
            </VTabs>

            <VCard class="mt-5">
              <VCardText>
                <VWindow v-model="saveTab">
                  <VWindowItem
                    v-if="operType == -1 || operType == 3"
                    :key="0"
                  >
                    <VAutocomplete
                      v-model="elOption"
                      class="flow-mt-12"
                      variant="outlined"
                      label="选择EL配置"
                      :items="elOptions"
                      item-title="elName"
                      item-value="id"
                      clearable
                      :disabled="elOptionDisabled"
                    />
                    <VAutocomplete
                      v-model="executorOption"
                      class="flow-mt-12"
                      variant="outlined"
                      label="选择执行器"
                      :items="executorOptions"
                      item-title="executorName"
                      item-value="id"
                      clearable
                    />
                  </VWindowItem>
                  <VWindowItem
                    v-if="operType == -1 || operType == 2"
                    :key="1"
                  >
                    <VTextField
                      v-model="elId"
                      class="flow-mt-12"
                      label="表达式ID"
                      counter
                      maxlength="50"
                    />
                    <VTextField
                      v-model="elName"
                      class="flow-mb-12"
                      label="表达式名称"
                      counter
                      maxlength="50"
                    />
                    <VAutocomplete
                      v-model="executorOption"
                      class="flow-mt-12"
                      variant="outlined"
                      label="选择执行器"
                      :items="executorOptions"
                      item-title="executorName"
                      item-value="id"
                      clearable
                    />
                  </VWindowItem>
                </VWindow>
              </VCardText>
            </VCard>

            <VBtn
              size="small"
              class="flow-mt-24 flow-w-100"
              @click="saveFlowDialogClick"
            >
              保存
            </VBtn>
          </VCardText>
        </VCard>
      </VDialog>
    </div>
  </div>
</template>

<style scoped>
.container {
  block-size: 100%;
  inline-size: 100%;
}

.flow-chart {
  position: relative;
  block-size: 95%;
  inline-size: 100%;
  margin-block-start: 8px;
}

.flow-chart-root {
  block-size: calc(100vh - 180px);
}

.flow-chart-root2 {
  block-size: 100%;
}

.flow-chart /deep/ .lf-red-node,
.flow-chart /deep/ .lf-element-text {
  cursor: move;
}

.flow-chart /deep/ svg {
  display: block;
}

.flow-chart-palette {
  position: absolute;
  z-index: 1;
  inset-block-start: 0;
  inset-inline-start: 0;
}

.setting-panel {
  position: absolute;
  block-size: calc(100% - 120px);
  inset-block-start: 0;
  inset-inline-end: 0;
}

.button-group button {
  margin-inline-end: 8px;
}

.view-json {
  box-shadow: none;
}

.view-json .v-card-text {
  padding: 0 !important;
}

.flow-mb-12 {
  margin-block-end: 12px;
}

.flow-mt-12 {
  margin-block-start: 12px;
}

.flow-mt-24 {
  margin-block-start: 24px;
}

.flow-w-100 {
  inline-size: 100%;
}
</style>

<style>
.node-red-palette {
  background-color: #fff;
}

.lf-local-mini-map {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/></svg>');
  block-size: 100px;
  inline-size: 100px;
}

.flow-alert-top {
  position: absolute !important;
  z-index: 0 !important;
  border-radius: 0 !important;
  background-color: #f1ecec00 !important;
  color: #000 !important;
  inset-block-start: 0 !important;
  margin-inline-start: 150px;
}

.flow-alert {
  position: absolute !important;
  z-index: 100 !important;
  border-radius: 0 !important;
  inline-size: 100% !important;
  inset-block-end: 0 !important;
}

.flow-alert .v-alert__content {
  word-wrap: break-word;
}

.el-code .language-js {
  white-space: break-spaces !important;
}

.fullscreen-div {
  position: fixed;
  z-index: 1005; /* 设置 z-index 以确保该元素在顶层 */
  background-color: #f8f7fa; /* 设置背景色，可根据需求更改 */
  block-size: 100%;
  inline-size: 100%;
  inset-block-start: 0;
  inset-inline-start: 0;
}
</style>

<style scoped>
.setting-panel {
  overflow: hidden;
  padding: 10px;
  background: transparent;

  /* block-size: calc(100vh - 330px); */
  inline-size: 350px;
  margin-block-start: 66px;
  margin-inline-end: 14px;
}

</style>

<style>
.resizable-div {
  position: relative;
}

.resizable-handle {
  position: absolute;
  z-index: 1005;
  background-color: transparent;
  block-size: 100%;
  cursor: ew-resize;
  inline-size: 8px;
  inset-block-start: 0;
  inset-inline-start: 0;
}

.resizable-handle:hover{
  background-color: #dbdbdb;
}

.lf-control {
  padding-block: 0;
  padding-inline: 30px;
}
</style>
